package com.yk.common.excel.core;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.metadata.data.CellData;
import com.yk.common.core.domain.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;

/**
 * Excel 导入监听
 *
 * @author lmx
 * @date 2023/10/25 11:24
 */
@Slf4j
public class DefaultExcelListener<T> extends AnalysisEventListener<T> {

    /**
     * 导入回执
     */
    private final ExcelResult<T> excelResult;

    /**
     * 检查实例
     */
    private final CheckService<T> checkService;

    public DefaultExcelListener(CheckService<T> checkService) {
        this.excelResult = new ExcelResult<>();
        excelResult.setList(Lists.newArrayList());
        this.checkService = checkService;
    }

    public ExcelResult<T> getExcelResult() {
        return excelResult;
    }

    /**
     * 处理异常
     *
     * @param exception ExcelDataConvertException
     * @param context   Excel 上下文
     */
    @Override
    public void onException(Exception exception, AnalysisContext context) {
        log.error("解析失败：{}", exception);
        if (exception instanceof ExcelDataConvertException) {
            ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;
            CellData<?> cellData = excelDataConvertException.getCellData();
            CellDataTypeEnum type = cellData.getType();
            String out = null;
            switch (type) {
                case STRING:
                    out = cellData.getStringValue();
                    break;
                case NUMBER:
                    out = cellData.getNumberValue().toString();
                    break;
                case BOOLEAN:
                    out = cellData.getBooleanValue().toString();
                    break;
                default:
                    break;
            }
            String errMsg = String.format("第%d行，第%d列解析异常，数据为:%s", excelDataConvertException.getRowIndex() + 1,
                    excelDataConvertException.getColumnIndex() + 1, out);
            throw new ExcelAnalysisException(errMsg);
        }
        throw new ExcelAnalysisException("表数据解析失败");
    }

    @Override
    public void invoke(T data, AnalysisContext context) {
        Integer rowIndex = context.readRowHolder().getRowIndex();
        ExcelRecord<T> record = new ExcelRecord<>();
        record.setRowIndex(rowIndex + 1);
        record.setData(data);
        Result<T> checkResult = checkService.check(data);
        if (!checkResult.isSuccess()) {
            record.setErrorMsg(checkResult.getMsg());
        }
        excelResult.getList().add(record);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        log.debug("所有数据解析完成！");
    }
}
